package com.tanhua.server.service;
import com.tanhua.domain.db.*;
import com.tanhua.domain.enums.ConclusionEnum;
import com.tanhua.domain.enums.CoverEnum;
import com.tanhua.domain.vo.*;
import com.tanhua.dubbo.api.*;
import com.tanhua.server.interceptor.UserHolder;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.BeanUtils;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;

@Service
@Slf4j
public class TestSoulService {

	@Reference
	private SoulPaperApi soulPaperApi;
	@Reference
	private SoulPaperQuestionApi soulPaperQuestionApi;
	@Reference
	private SoulQuestionApi soulQuestionApi;
	@Reference
	private SoulOptionsApi soulOptionsApi;
	@Reference
	private SoulReportApi soulReportApi;
	@Reference
	private UserInfoApi userInfoApi;


	/**
	 * 接口名称：测灵魂-问卷列表
	 * 接口路径：GET/testSoul
	 */
	public ResponseEntity<Object> soulPaperList() {
		log.info("测灵魂-问卷列表");
		// 获取当前用户id
		Long userId = UserHolder.getUserId();

		// 创建三个paperListVo (初中高三个问卷)
		PaperListVo primaryPaper = new PaperListVo();
		PaperListVo middlePaper = new PaperListVo();
		PaperListVo seniorPaper = new PaperListVo();

		// 查询报告list
		List<SoulReport> reportList = soulReportApi.findReportListByUserId(userId);
		int size = reportList.size();

		// 设置问卷封装的公共方法
		setPaperListVo(primaryPaper,1L);//id为问卷id
		setPaperListVo(middlePaper,2L);
		setPaperListVo(seniorPaper,3L);

		primaryPaper.setIsLock(0);
		// 判断
		if (size == 0) {
			// 即是初级都是解锁的
			primaryPaper.setReportId(null);
			middlePaper.setIsLock(1);
			middlePaper.setReportId(null);
			seniorPaper.setIsLock(1);
			seniorPaper.setReportId(null);

		} else if (size == 1) {
			// 即是有一份初级的报告,中级问卷要解锁
			middlePaper.setIsLock(0);
			middlePaper.setReportId(null);
			seniorPaper.setIsLock(1);
			seniorPaper.setReportId(null);
			for (SoulReport soulReport : reportList) {
				if (soulReport.getPaperId() == 1) {
					primaryPaper.setReportId(soulReport.getId().toString());
				}
			}
		} else if (size == 2) {
			// 即是初中级都生成报告
			middlePaper.setIsLock(0);
			seniorPaper.setIsLock(0);
			for (SoulReport soulReport : reportList) {
				if (soulReport.getPaperId() == 1) {
					primaryPaper.setReportId(soulReport.getId().toString());
				} else if (soulReport.getPaperId() == 2) {
					middlePaper.setReportId(soulReport.getId().toString());
				}
			}
		} else if (size == 3) {
			// 即是初中高级都生成报告
			middlePaper.setIsLock(0);
			seniorPaper.setIsLock(0);
			for (SoulReport soulReport : reportList) {
				if (soulReport.getPaperId() == 1) {
					primaryPaper.setReportId(soulReport.getId().toString());
				} else if (soulReport.getPaperId() == 2) {
					middlePaper.setReportId(soulReport.getId().toString());
				} else if (soulReport.getPaperId() == 3) {
					seniorPaper.setReportId(soulReport.getId().toString());
				}
			}
		}
		// 三套问卷添加到集合
		List<PaperListVo> list = new ArrayList();
		list.add(primaryPaper);
		list.add(middlePaper);
		list.add(seniorPaper);

		// 返回
		return ResponseEntity.ok(list);
	}

	/**
	 * 封装问卷的公共方法
	 */
	private void setPaperListVo(PaperListVo paperListVo, Long id) {
		SoulPaper soulPaper = soulPaperApi.findById(id);
		// 设置问卷编号
		paperListVo.setId(id.toString());
		// 设置星别
		paperListVo.setStar(soulPaper.getStar().intValue());
		BeanUtils.copyProperties(soulPaper,paperListVo);

		// 分别查询题目与选项组成试题
		// 先根据问卷级别查询出所有的试题id
		List<SoulPaperQuestion> soulPaperQuestionList =  soulPaperQuestionApi.findQuestionList(id);
		// 返回的试题list集合
		//List<Map<String,Object>> questions = new ArrayList<>();
		List<QuestionsVo> questions = new ArrayList<>();
		// 查询题目 与其所有选项 组合成试题
		if (!CollectionUtils.isEmpty(soulPaperQuestionList)) {
			for (SoulPaperQuestion soulPaperQuestion : soulPaperQuestionList) {
				// 创建试题返回vo
				QuestionsVo questionsVo = new QuestionsVo();
				// 拿到第一个试题
				SoulQuestion soulQuestion = soulQuestionApi.findById(soulPaperQuestion.getQuestionId());
				// 返回的list的第一份问卷map
				questionsVo.setId(soulQuestion.getId().toString());
				questionsVo.setQuestion(soulQuestion.getQuestion());
				/*Map<String,Object> map = new HashMap<>();
				map.put("id",soulPaperQuestion.getQuestionId());
				map.put("question",soulQuestion.getQuestion());//题目*/
				// 返回的选项VO集合
				List<OptionsVo> optionsVoList = new ArrayList<>();
				List<SoulOptions> soulOptionsList = soulOptionsApi.findByQuestionId(soulQuestion.getId());
				if (!CollectionUtils.isEmpty(soulOptionsList)) {
					for (SoulOptions soulOption : soulOptionsList) {
						OptionsVo optionsVo = new OptionsVo();
						optionsVo.setId(soulOption.getId().toString());
						optionsVo.setOption(soulOption.getOptions());//选项
						// 将第一题的选项添加到vo集合
						optionsVoList.add(optionsVo);
					}
				}
				// 将选项vo集合添加到map,与前面的题目组成试题
				/*map.put("options",optionsVoList);
				questions.add(map);*/
				questionsVo.setOptions(optionsVoList);
				questions.add(questionsVo);
			}
		}
		// 获取到全部试题后添加到问卷中
		paperListVo.setQuestions(questions);
	}

	/**
	 * 接口名称：测灵魂-提交问卷
	 * 接口路径：POST/testSoul
	 */
	public ResponseEntity<Object> submitSoulPaper(Map<String, List<Answers>> map) {
		log.info("测灵魂-提交问卷");
		Long userId = UserHolder.getUserId();
		//计算得分
		Long totalScore = 0L;
		Long questionId = 0L;

		// 获取用户问卷回答
		Collection<List<Answers>> answersList = map.values();
		// 遍历获取用户的试题id和选项
		for (List<Answers> answers : answersList) {
			// 试题id
			for (Answers answer : answers) {
				questionId = Long.parseLong(answer.getQuestionId());
				// 获取选项的字符串
				String optionId = answer.getOptionId();
				// 根据试题id和选项id获取选项,从而得到选项分数
				SoulOptions soulOptions = soulOptionsApi.findByQuestionIdAndOptionId(questionId,optionId);
				Long score = soulOptions.getScore();
				totalScore += score;
			}
		}
		// 通过试题id查询中间表获取当前提交的是哪套问卷,有报告则更新,没有就插入数据库
		SoulPaperQuestion soulPaperQuestion = soulPaperQuestionApi.findOneByQuestionId(questionId);

		// 再通过问卷id和用户id去查询是否有当前问卷的报告,有报告则更新,没有就插入数据库
		SoulReport soulReport = soulReportApi.findByUserIdAndPaperId(userId,soulPaperQuestion.getPaperId());
		SoulReport newSoulReport = null;
		if (soulReport != null) {
			// 不为空即更新得分,返回id
			newSoulReport = new SoulReport();
			newSoulReport.setScore(totalScore);
			BeanUtils.copyProperties(soulReport,newSoulReport);
			soulReportApi.update(newSoulReport);
			return ResponseEntity.ok(soulReport.getId());
		}
		// 为空则插入问卷数据,返回报告id
		newSoulReport = new SoulReport();
		newSoulReport.setUserId(userId);
		newSoulReport.setPaperId(soulPaperQuestion.getPaperId());
		newSoulReport.setScore(totalScore);
		newSoulReport.setCreated(new Date());
		newSoulReport.setUpdated(new Date());
		Long reportId = soulReportApi.save(newSoulReport);

		return ResponseEntity.ok(reportId.toString());
	}

	/**
	 * 接口名称：测灵魂-查看结果
	 * 接口路径：GET/testSoul/report/:id
	 */
	public ResponseEntity<Object> findReportList(Long reportId) {
		log.info("测灵魂-查看结果");
		Long userId = UserHolder.getUserId();

		// 根据报告id查询报告
		SoulReport soulReport = soulReportApi.findById(reportId);
		if (soulReport == null) {
			return ResponseEntity.ok(ErrorResult.error());
		}
		Long score = soulReport.getScore();

		// 创建返回的soulReportVo
		SoulReportVo soulReportVo = new SoulReportVo();

		// 创建维度项集合
		List<SoulDimensions> dimensionsList = new ArrayList<>();
		// 创建相似的人集合
		//List<SoulSimilarYou> soulSimilarYouList = new ArrayList<>();

		// 根据分值计算范围内的用户
		Long minSimilarScore = 0L;
		Long maxSimilarScore = 0L;
		// 创建报告集合,用于接收根据分数查询的相似的人的
		//List<SoulReport> similarUserIdList = new ArrayList<>();

		if (score <= 20) {
			soulReportVo.setConclusion(ConclusionEnum.OWL.getValue());
			soulReportVo.setCover(CoverEnum.OWL.getValue());
			//// 维度项（外向，判断，抽象，理性）
			SoulDimensions firstDimensions = new SoulDimensions("外向","70%");
			SoulDimensions secondDimensions = new SoulDimensions("判断","80%");
			SoulDimensions thirdDimensions = new SoulDimensions("抽象","60%");
			SoulDimensions fourthDimensions = new SoulDimensions("理性","90%");
			Collections.addAll(dimensionsList,firstDimensions,secondDimensions,thirdDimensions,fourthDimensions);
			// 设置维度到VO
			soulReportVo.setDimensions(dimensionsList);
			// 根据分数范围查询与我相似的人
			maxSimilarScore = 20L;
			// 调用公共方法设置相似的人
			this.setVoSimilarYou(soulReportVo,userId,minSimilarScore,maxSimilarScore);

		} else if (score <= 40) {
			soulReportVo.setConclusion(ConclusionEnum.RABBIT.getValue());
			soulReportVo.setCover(CoverEnum.RABBIT.getValue());
			//// 维度项（外向，判断，抽象，理性）
			SoulDimensions firstDimensions = new SoulDimensions("外向","80%");
			SoulDimensions secondDimensions = new SoulDimensions("判断","80%");
			SoulDimensions thirdDimensions = new SoulDimensions("抽象","70%");
			SoulDimensions fourthDimensions = new SoulDimensions("理性","80%");
			Collections.addAll(dimensionsList,firstDimensions,secondDimensions,thirdDimensions,fourthDimensions);
			// 设置维度到VO
			soulReportVo.setDimensions(dimensionsList);
			// 查询与我相似的人
			minSimilarScore = 21L;
			maxSimilarScore = 40L;
			// 调用公共方法设置相似的人
			this.setVoSimilarYou(soulReportVo,userId,minSimilarScore,maxSimilarScore);

		} else if (score <= 55) {

			soulReportVo.setConclusion(ConclusionEnum.FOX.getValue());
			soulReportVo.setCover(CoverEnum.FOX.getValue());
			//// 维度项（外向，判断，抽象，理性）
			SoulDimensions firstDimensions = new SoulDimensions("外向","90%");
			SoulDimensions secondDimensions = new SoulDimensions("判断","80%");
			SoulDimensions thirdDimensions = new SoulDimensions("抽象","90%");
			SoulDimensions fourthDimensions = new SoulDimensions("理性","80%");
			Collections.addAll(dimensionsList,firstDimensions,secondDimensions,thirdDimensions,fourthDimensions);
			// 设置维度到VO
			soulReportVo.setDimensions(dimensionsList);
			// 查询与我相似的人
			minSimilarScore = 41L;
			maxSimilarScore = 55L;

			// 调用公共方法设置相似的人
			this.setVoSimilarYou(soulReportVo, userId, minSimilarScore, maxSimilarScore);

		} else  {
			soulReportVo.setConclusion(ConclusionEnum.LION.getValue());
			soulReportVo.setCover(CoverEnum.LION.getValue());
			//// 维度项（外向，判断，抽象，理性）
			SoulDimensions firstDimensions = new SoulDimensions("外向","80%");
			SoulDimensions secondDimensions = new SoulDimensions("判断","90%");
			SoulDimensions thirdDimensions = new SoulDimensions("抽象","80%");
			SoulDimensions fourthDimensions = new SoulDimensions("理性","90%");
			Collections.addAll(dimensionsList,firstDimensions,secondDimensions,thirdDimensions,fourthDimensions);
			// 设置维度到VO
			soulReportVo.setDimensions(dimensionsList);
			// 查询与我相似的人
			minSimilarScore = 56L;
			maxSimilarScore = 100L;
			/*similarUserIdList = soulReportApi.findSimilarByScore(userId,minSimilarScore,maxSimilarScore);
			if (!CollectionUtils.isEmpty(similarUserIdList)) {
				for (SoulReport report : similarUserIdList) {
					SoulSimilarYou soulSimilarYou = new SoulSimilarYou();
					// 通过相似的人id获取用户信息(头像)
					UserInfo userInfo = userInfoApi.findById(report.getUserId());
					if (userInfo != null) {
						soulSimilarYou.setId(userInfo.getId().intValue());
						soulSimilarYou.setAvatar(userInfo.getAvatar());
					}
					// 添加到相似的人list
					soulSimilarYouList.add(soulSimilarYou);
				}
			}
			// 设置到soulReportVo
			soulReportVo.setSimilarYou(soulSimilarYouList);*/
			// 调用公共方法设置相似的人
			this.setVoSimilarYou(soulReportVo,userId,minSimilarScore,maxSimilarScore);

		}
		// 返回
		return ResponseEntity.ok(soulReportVo);
	}

	/**
	 * 抽取公共方法:设置soulReportVo的SimilarYou
	 */
	public void setVoSimilarYou(SoulReportVo soulReportVo,
										Long userId,Long minSimilarScore,Long maxSimilarScore) {

		List<SoulSimilarYou> soulSimilarYouList = new ArrayList<>();
		List<SoulReport> similarUserIdList = soulReportApi.findSimilarByScore(userId,minSimilarScore,maxSimilarScore);
		if (!CollectionUtils.isEmpty(similarUserIdList)) {
			for (SoulReport report : similarUserIdList) {
				SoulSimilarYou soulSimilarYou = new SoulSimilarYou();
				// 通过相似的人id获取用户信息(头像)
				UserInfo userInfo = userInfoApi.findById(report.getUserId());
				if (userInfo != null) {
					soulSimilarYou.setId(userInfo.getId().intValue());
					soulSimilarYou.setAvatar(userInfo.getAvatar());
				}
				// 添加到相似的人list
				soulSimilarYouList.add(soulSimilarYou);
			}
		}
		// 设置到soulReportVo
		soulReportVo.setSimilarYou(soulSimilarYouList);

	}
}
